;;; Copyright (C) 2011-2012 Alessio Stalla
;;;
;;; This program is free software: you can redistribute it and/or modify
;;; it under the terms of the GNU General Public License as published by
;;; the Free Software Foundation, either version 3 of the License, or
;;; (at your option) any later version.
;;;
;;; This program is distributed in the hope that it will be useful,
;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;;; GNU General Public License for more details.
;;;
;;; You should have received a copy of the GNU General Public License
;;; along with this program.  If not, see <http://www.gnu.org/licenses/>.

(defpackage html+js
  (:use :cl :html :tag-pool :parenscript)
  (:shadowing-import-from :html #:label) ;;Conflicts with parenscript:label
  (:export #:verbatim #:with-inline-html))

(in-package :html+js)

(dotags (tag)
  (eval `(defpsmacro ,tag (&rest args)
           (let ((tag-pool::*constant-string* "")
                 (tag-pool:*output-encoding* nil))
             `(progn
                ,(macroexpand-1 `(,',tag ,@args))
                ,(tag-pool::emit-flush))))))

(defmacro with-inline-html (&body body)
  (let ((x (gensym "tag-pool-out")))
    `(let ((,x ""))
       (macrolet ((tag-pool:emit-expression (str)
                    (let ((g (gensym "str")))
                      `(let ((,g ,str))
                         (when ,g
                           (setf ,',x (concatenate 'string ,',x ,g)))
                         t)))
                  (tag-pool:emit-constant-string (str)
                    `(setf ,',x (concatenate 'string ,',x ,str))))
         ,@body)
       ,x)))

(import-macros-from-lisp 'with-inline-html)

(defmethod tag-pool:emit-tag-body-form ((tag script) form)
  (call-next-method
   tag
   `(out (ps:ps (macrolet ((verbatim (form)
                             `(ps:lisp (progn (princ ,form ps::*psw-stream*)
                                              '(progn)))))
                  ,form)))))

(defmethod tag-pool:emit-tag-attribute ((tag tag) (attr (eql :onclick)) value)
  (call-next-method tag attr `(ps:ps ,value)))

#||
(ps:ps* `(ps:create :wp 0 :wn ,1 :wf (ps:create :foo "foo" :bar nil :baz t :kaz ps:f)))

(ps:ps (ps:create :wp 0 :wn 1 :wf (ps:create :foo "foo" :bar nil :baz t :kaz ps:f)))

(with-output-to-string (tag-pool:*tag-output-stream*)
  (html:html
    (html:head
      (html:title "Parenscript Example"))
    (html:body
      (html:script
       (defun foo ()
         (html+js::with-inline-html
           (html:div "static content" (dotimes (i 3) (html:p (tag-pool:out "hey! " i))))))))))
||#
